#include <iostream>
#include <string>
#include <vector>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>

void Usage(std::string proc)
{
    std::cout << "请使用如下格式运行程序：" << std::endl;
    std::cout << "Usage: " << proc << " process-num" << std::endl;
}

// master
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(1);
    }

    // 1.创建多个管道，每个子进程一个
    int process_num = atoi(argv[1]);
    int pipefds[process_num][2];
    for (int i = 0; i < process_num; ++i)
    {
        if (pipe(pipefds[i]) < 0)
        {
            std::cerr << "pipe error" << std::endl;
            exit(2);
        }
    }

    // 2.创建子进程
    for (int i = 0; i < process_num; ++i)
    {
        pid_t pid = fork();
        if (pid < 0)
        {
            std::cerr << "fork error" << std::endl;
            exit(3);
        }
        else if (pid == 0)
        {
            // 子进程关闭写端（其他管道的读端也关闭）
            for (int j = 0; j < process_num; ++j)
            {
                if (j != i) close(pipefds[j][0]);
                close(pipefds[j][1]);
            }
            while (true)
            {
                int task_id;
                ssize_t s = read(pipefds[i][0], &task_id, sizeof(task_id));
                if (s == 0) break; // 父进程关闭管道，子进程退出
                if (s > 0)
                {
                    std::cout << "child " << i << " processing task " << task_id << std::endl;
                }
            }
            close(pipefds[i][0]); // 子进程关闭自己的读端
            exit(0);
        }
    }

    // 父进程逻辑
    for (int i = 0; i < process_num; ++i)
    {
        close(pipefds[i][0]); // 父进程关闭所有管道的读端
    }
    int task_id = 1;
    while (task_id <= 10) // 假设有10个任务
    {
        for (int i = 0; i < process_num && task_id <= 10; ++i)
        {
            write(pipefds[i][1], &task_id, sizeof(task_id));
            ++task_id;
        }
    }
    for (int i = 0; i < process_num; ++i)
    {
        close(pipefds[i][1]); // 父进程关闭所有管道的写端
    }

    // 等待所有子进程结束
    for (int i = 0; i < process_num; ++i)
    {
        wait(nullptr);
    }

    return 0;
}